#![allow(unused_imports,dead_code)]
use super::{GoodsBean,CustOrderBean,PayTypeBean,StatusBean,OrderItemBean,GoodsTypeBean,RecommendBean,RoleBean,PermissionBean,UserBean};
use sqlx::mysql::{MySqlRow,MySqlPoolOptions};
use sqlx::{FromRow, MySqlPool};
use std::sync::Arc;

pub struct Table<'c, T>
where
	T: FromRow<'c, MySqlRow>,
{
	pub pool: Arc<Option<MySqlPool>>,
	_from_row: fn(&'c MySqlRow) -> Result<T, sqlx::Error>,
}

impl<'c, T> Table<'c, T>
where
	T: FromRow<'c, MySqlRow>,
{
	fn new(pool: Arc<Option<MySqlPool>>) -> Self {
		Table {
			pool,
			_from_row: T::from_row,
		}
	}
}

pub struct JoinTable<'c, T1, T2>
where
	T1: FromRow<'c, MySqlRow>,
	T2: FromRow<'c, MySqlRow>,
{
	pub pool: Arc<Option<MySqlPool>>,
	_from_row: (
		fn(&'c MySqlRow) -> Result<T1, sqlx::Error>,
		fn(&'c MySqlRow) -> Result<T2, sqlx::Error>,
	),
}

#[allow(dead_code)]
impl<'c, T1, T2> JoinTable<'c, T1, T2>
where
	T1: FromRow<'c, MySqlRow>,
	T2: FromRow<'c, MySqlRow>,
{
	fn new(pool: Arc<Option<MySqlPool>>) -> Self {
		JoinTable {
			pool,
			_from_row: (T1::from_row, T2::from_row),
		}
	}
}

pub struct Database<'c> {
	pub goodses: Arc<Table<'c, GoodsBean>>,
	pub cust_orders: Arc<Table<'c, CustOrderBean>>,
	pub pay_types: Arc<Table<'c, PayTypeBean>>,
	pub statuses: Arc<Table<'c, StatusBean>>,
	pub order_items: Arc<Table<'c, OrderItemBean>>,
	pub goods_types: Arc<Table<'c, GoodsTypeBean>>,
	pub recommends: Arc<Table<'c, RecommendBean>>,
	pub roles: Arc<Table<'c, RoleBean>>,
	pub permissions: Arc<Table<'c, PermissionBean>>,
	pub users: Arc<Table<'c, UserBean>>,
}

impl Database<'_> {
	pub async fn new(_sql_url: &str) -> Database<'_> {
		let pool = Some(MySqlPoolOptions::new().connect(&_sql_url).await.unwrap());
		let pool = Arc::new(pool);

		Database {
			goodses: Arc::from(Table::new(pool.clone())),
			cust_orders: Arc::from(Table::new(pool.clone())),
			pay_types: Arc::from(Table::new(pool.clone())),
			statuses: Arc::from(Table::new(pool.clone())),
			order_items: Arc::from(Table::new(pool.clone())),
			goods_types: Arc::from(Table::new(pool.clone())),
			recommends: Arc::from(Table::new(pool.clone())),
			roles: Arc::from(Table::new(pool.clone())),
			permissions: Arc::from(Table::new(pool.clone())),
			users: Arc::from(Table::new(pool.clone())),
		}
	}
}
